#region Copyright RenGuiYou. All rights reserved.
//=====================================================
// PandoraFrameWork
// Author:      RenGuiyou
// Feedback: 	mailto:750539605@qq.com
//=====================================================
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Pandora;
using UnityEditor;
using UnityEngine;

namespace PandoraEditor.Window
{
    public class PanelSet<T> : IEnumerable<KeyValuePair<string, BoxSet<T>>> where T : UnityEngine.Object
    {
        private Dictionary<string, BoxSet<T>> m_BoxSet;

        public PanelSet()
        {
            m_BoxSet = new Dictionary<string, BoxSet<T>>();
        }

        public void Add(string title, object key, T val)
        {
            if (!m_BoxSet.ContainsKey(title))
            {
                m_BoxSet.Add(title, new BoxSet<T>());
            }
            m_BoxSet[title].Add(key, val);
        }

        public void Clear()
        {
            m_BoxSet.Clear();
        }

        public bool Contains(string key)
        {
            return m_BoxSet.ContainsKey(key);
        }

        public BoxSet<T> this[string key]
        {
            get { return m_BoxSet[key]; }
        }

        public int Count
        {
            get { return m_BoxSet.Count; }
        }

        IEnumerator<KeyValuePair<string, BoxSet<T>>> IEnumerable<KeyValuePair<string, BoxSet<T>>>.GetEnumerator()
        {
            return m_BoxSet.GetEnumerator();
        }

        public IEnumerator GetEnumerator()
        {
            return m_BoxSet.GetEnumerator();
        }
    }

    public class BoxSet<T> : IEnumerable<KeyValuePair<string, List<T>>> where T : UnityEngine.Object
    {
        private Dictionary<string, List<T>> m_ResultSet;

        public BoxSet()
        {
            m_ResultSet = new Dictionary<string, List<T>>();
        }

        public void Add(object obj, T val)
        {
            string key = obj.ToString();
            if (m_ResultSet.ContainsKey(key))
            {
                if (!m_ResultSet[key].Contains(val))
                {
                    m_ResultSet[key].Add(val);
                }
            }
            else
            {
                m_ResultSet.Add(key, new List<T> { val });
            }
        }

        public List<T> this[string key]
        {
            get { return m_ResultSet[key]; }
        }

        public int Count
        {
            get { return m_ResultSet.Count; }
        }

        public IEnumerator<KeyValuePair<string, List<T>>> GetEnumerator()
        {
            return m_ResultSet.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return m_ResultSet.GetEnumerator();
        }
    }

    public abstract class IDrawPanel
    {
        protected static PdrWindow m_Window { get { return PdrWindow.PandoraWindow; } }

        public abstract void DrawPanel();

        public static void DrawResultSet<T>(PanelSet<T> ResultSet, ref Vector2 ResultPanelScrollView)
            where T : UnityEngine.Object
        {
            GUILayout.BeginVertical();
            {
                ResultPanelScrollView = EditorGUILayout.BeginScrollView(ResultPanelScrollView);
                foreach (KeyValuePair<string, BoxSet<T>> resutSet in ResultSet)
                {
                    GUILayout.BeginVertical(); //内大框
                    {
                        GUILayout.BeginVertical();
                        {
                            EditorGUILayout.LabelField(resutSet.Key, EditorStyles.boldLabel);
                            GUILayout.BeginHorizontal("box");
                            {
                                GUILayout.Space(5);
                                foreach (var valList in resutSet.Value)
                                {
                                    GUILayout.BeginVertical(GUILayout.MaxWidth(400));
                                    EditorGUILayout.LabelField(
                                        string.Format("{0}: ({1})", valList.Key, valList.Value.Count),
                                        EditorStyles.boldLabel);
                                    GUILayout.BeginVertical("box");
                                    foreach (var val in valList.Value)
                                    {
                                        EditorGUILayout.ObjectField(val, typeof(T), true);
                                    }

                                    GUILayout.EndVertical();
                                    GUILayout.EndVertical();
                                }

                                GUILayout.Space(5);
                            }
                            GUILayout.EndHorizontal();
                        }
                        EditorGUILayout.EndVertical();
                    }
                    GUILayout.EndVertical();
                }

                EditorGUILayout.EndScrollView();
            }
            GUILayout.EndVertical();
        }
    }

    public class NavFuncBase<T> : IDrawPanel where T : UnityEngine.Object
    {
        private List<string> m_NavTitles = new List<string>();
        private List<string> m_FixTitles = new List<string>();
        private List<Action> m_NavActions = new List<Action>();
        private List<Action> m_FixActions = new List<Action>();

        private StringBuilder logHandle = new StringBuilder();

        protected PanelSet<T> m_ResultSet = new PanelSet<T>();

        private Vector2 m_NavFuncScrollView;
        private Vector2 m_ResultPanelScrollView;

        protected void AddNavButton(string title, Action action)
        {
            m_NavTitles.Add(title);
            m_NavActions.Add(action);
        }

        protected void AddFixButton(string title, Action action)
        {
            m_FixTitles.Add(title);
            m_FixActions.Add(action);
        }

        protected void AddClearButton()
        {
            AddFixButton("Clear", Clear);
        }

        #region LogFile

        public void LogOpen()
        {
            logHandle.Length = 0;
        }

        public void LogAppend(string info, AssetObject obj, UnityEngine.Object item = null)
        {
            string objectName = obj.name.Replace(".prefab", "");
            if (item)
            {
                LogAppend(info, objectName, item.name);
            }
            else
            {
                LogAppend(info, objectName);
            }
        }
        public void LogAppend(string info, UnityEngine.Object obj, UnityEngine.Object item = null)
        {
            if (item)
            {
                LogAppend(info, obj.name, item.name);
            }
            else
            {
                LogAppend(info, obj.name);
            }
        }

        public void LogAppend(string info, string objName, string itemName = null)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(string.Format("[info]:{0}\t", info));
            sb.Append(string.Format("[预制]:{0}\t", objName));
            if (!string.IsNullOrEmpty(itemName))
            {
                sb.Append(string.Format("[描述]:{0}\t", itemName));
            }
            LogAppend(sb.ToString());
        }

        public void LogAppend(string str)
        {
            logHandle.AppendLine(str);
        }

        public void WriteLog()
        {
            var array = ToString().Split('.');
            LogFile.WriteLog(array[array.Length - 1], logHandle.ToString());
        }
        #endregion

        #region Draw

        public override void DrawPanel()
        {
            GUILayout.Space(5f);
            GUILayout.BeginHorizontal();
            {
                if (m_NavTitles.Count > 0)
                {
                    GUILayout.BeginVertical(GUILayout.MaxWidth(100));
                    {
                        GUILayout.BeginVertical(GUILayout.Height(m_Window.position.height - 100));
                        {
                            GUILayout.Space(5f);
                            EditorGUILayout.LabelField("检测工具", EditorStyles.boldLabel);
                            GUILayout.BeginVertical("box", GUILayout.Height(m_Window.position.height - 150));
                            {
                                m_NavFuncScrollView = EditorGUILayout.BeginScrollView(m_NavFuncScrollView);
                                {
                                    DrawNavButtons();
                                }
                                EditorGUILayout.EndScrollView();

                            }
                            EditorGUILayout.EndVertical();
                        }
                        GUILayout.EndVertical();
                    }
                    GUILayout.EndVertical();
                }

                if (m_FixTitles.Count > 0)
                {
                    GUILayout.BeginVertical(GUILayout.MaxWidth(100));
                    {
                        GUILayout.BeginVertical(GUILayout.Height(m_Window.position.height - 100));
                        {
                            GUILayout.Space(5f);
                            EditorGUILayout.LabelField("修复工具", EditorStyles.boldLabel);
                            GUILayout.BeginVertical("box", GUILayout.Height(m_Window.position.height - 150));
                            {
                                m_NavFuncScrollView = EditorGUILayout.BeginScrollView(m_NavFuncScrollView);
                                {
                                    DrawFixButtons();
                                }
                                EditorGUILayout.EndScrollView();

                            }
                            EditorGUILayout.EndVertical();
                        }
                        GUILayout.EndVertical();
                    }
                    GUILayout.EndVertical();
                }

                DrawResultSet(m_ResultSet, ref m_ResultPanelScrollView);
            }
            GUILayout.EndHorizontal();
        }

        private void DrawNavButtons()
        {
            for (int i = 0; i < m_NavTitles.Count; i++)
            {
                GUILayout.Space(5);
                if (GUILayout.Button(m_NavTitles[i], GUILayout.Height(25)))
                {
                    m_NavActions[i].Invoke();
                }
            }
        }

        private void DrawFixButtons()
        {
            for (int i = 0; i < m_FixTitles.Count; i++)
            {
                GUILayout.Space(5);
                if (GUILayout.Button(m_FixTitles[i], GUILayout.Height(25)))
                {
                    m_FixActions[i].Invoke();
                }
            }
        }

        protected void Clear()
        {
            m_ResultSet.Clear();
            LogOpen();
        }
    }
    #endregion
}
